# 顶层 CMake 项目文件：在此处执行全局配置并包含子项目。

# cmake 最低版本支持
cmake_minimum_required(VERSION 3.10)


# 项目名称及版本
project(LearnCppDemo VERSION 1.0.0)
message(STATUS "-----------------------------------------------------------------------------------")
message(STATUS "开始编译构建项目（当前在顶层 CMake 中）")
message(STATUS "项目名称："   ${PROJECT_NAME})
message(STATUS "项目版本号：" ${PROJECT_VERSION})

# 设置项目自定义全局变量
# * 定义：学习案例演示可执行程序的名称
set(APP_NAME_LEARN_DEMO_APP LearnDemoApp)
# * 定义：学习案例演示可执行程序的输出路径
set(APP_EXECUTABLE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/out)

# * 定义：CommonSupport 模块的库文件名
set(LIB_NAME_COMMON_SUPPORT CommonSupport)
# * 定义：CommonSupport 模块库的头文件引入路径
set(LIB_HEAD_FILE_PATH_COMMON_SUPPORT ${CMAKE_CURRENT_SOURCE_DIR}/CommonSupport)

# * 定义：LearnAlgorithm 模块的库文件名
set(LIB_NAME_LEARN_ALGORITHM LearnAlgorithm)
# * 定义：LearnAlgorithm 模块库的头文件引入路径
set(LIB_HEAD_FILE_PATH_LEARN_ALGORITHM ${CMAKE_CURRENT_SOURCE_DIR}/LearnAlgorithm)

# * 定义：LearnCase 模块库文件名
set(LIB_NAME_LEARN_CASE LearnCase)
# * 定义：LearnCase 模块库头文件引入路径
set(LIB_HEAD_FILE_PATH_LEARN_CASE ${CMAKE_CURRENT_SOURCE_DIR}/LearnCase)

# * 定义：LearnDesignPattern 模块库文件名
set(LIB_NAME_LEARN_DESIGN_PATTERN LearnDesignPattern)
# * 定义：LearnDesignPattern 模块库头文件引入路径
set(LIB_HEAD_FILE_PATH_LEARN_DESIGN_PATTERN ${CMAKE_CURRENT_SOURCE_DIR}/LearnDesignPattern)

# * 定义：LearnSerialization 模块的库文件名
set(LIB_NAME_LEARN_SERIALIZATION LearnSerialization)
# * 定义：LearnSerialization 模块库的头文件引入路径
set(LIB_HEAD_FILE_PATH_LEARN_SERIALIZATION ${CMAKE_CURRENT_SOURCE_DIR}/LearnSerialization)

# * 定义：LearnSocket 模块的库文件名
set(LIB_NAME_LEARN_SOCKET LearnSocket)
# * 定义：LearnSocket 模块库的头文件引入路径
set(LIB_HEAD_FILE_PATH_LEARN_SOCKET ${CMAKE_CURRENT_SOURCE_DIR}/LearnSocket)

# * 定义：LearnThread 模块的库文件名
set(LIB_NAME_LEARN_THREAD LearnThread)
# * 定义：LearnThread 模块库的头文件引入路径
set(LIB_HEAD_FILE_PATH_LEARN_THREAD ${CMAKE_CURRENT_SOURCE_DIR}/LearnThread)


# 输出相关变量数据，以便查找问题。
message(STATUS "项目自定义全局变量如下：")
message(STATUS "子模块可执行程序名：" ${APP_NAME_LEARN_DEMO_APP} "；可执行程序生成路径：" ${APP_EXECUTABLE_PATH})
message(STATUS "子模块库文件名：" ${LIB_NAME_COMMON_SUPPORT} "；源码及头文件路径：" ${LIB_HEAD_FILE_PATH_COMMON_SUPPORT})
message(STATUS "子模块库文件名：" ${LIB_NAME_LEARN_ALGORITHM} "；源码及头文件路径：" ${LIB_HEAD_FILE_PATH_LEARN_ALGORITHM})
message(STATUS "子模块库文件名：" ${LIB_NAME_LEARN_CASE} "；源码及头文件路径：" ${LIB_HEAD_FILE_PATH_LEARN_CASE})
message(STATUS "子模块库文件名：" ${LIB_NAME_LEARN_DESIGN_PATTERN} "；源码及头文件路径：" ${LIB_HEAD_FILE_PATH_LEARN_DESIGN_PATTERN})
message(STATUS "子模块库文件名：" ${LIB_NAME_LEARN_SERIALIZATION} "；源码及头文件路径：" ${LIB_HEAD_FILE_PATH_LEARN_SERIALIZATION})
message(STATUS "子模块库文件名：" ${LIB_NAME_LEARN_SOCKET} "；源码及头文件路径：" ${LIB_HEAD_FILE_PATH_LEARN_SOCKET})
message(STATUS "子模块库文件名：" ${LIB_NAME_LEARN_THREAD} "；源码及头文件路径：" ${LIB_HEAD_FILE_PATH_LEARN_THREAD})


# 设置第三方库全局变量
# * 定义：第三方库存放根路径
set(THIRD_PARTY_LIB_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/ThirdParty)
# * 定义：Json11 库
set(THIRD_PARTY_LIB_JSON11 ${THIRD_PARTY_LIB_ROOT}/Json11)
# * 定义：JsonCpp 库
set(THIRD_PARTY_LIB_JSONCPP ${THIRD_PARTY_LIB_ROOT}/JsonCpp)
# * 定义：Protobuf 库
set(THIRD_PARTY_LIB_PROTOBUF ${THIRD_PARTY_LIB_ROOT}/Protobuf)

# 输出相关变量数据，以便查找问题。
message(STATUS "第三方库全局变量如下：")
message(STATUS "第三方库根路径：" ${THIRD_PARTY_LIB_ROOT})
message(STATUS "第三方库 Json11 库：" ${THIRD_PARTY_LIB_JSON11})
message(STATUS "第三方库 JsonCpp 库：" ${THIRD_PARTY_LIB_JSONCPP})
message(STATUS "第三方库 Protobuf 库：" ${THIRD_PARTY_LIB_PROTOBUF})

# 引入依赖库文件的搜索目录
if(WIN32)
link_directories(
    ${THIRD_PARTY_LIB_JSONCPP}/libs/windows
    ${THIRD_PARTY_LIB_PROTOBUF}/libs/windows
)
else()
link_directories(
    ${THIRD_PARTY_LIB_JSONCPP}/libs/linux
    ${THIRD_PARTY_LIB_PROTOBUF}/libs/linux
)
endif()


# 全项目统一配置设置（子模块会继承顶层 CMake 配置）   
# set(CMAKE_CXX_STANDARD 17)                        # 使用 c++ 17 标准来编译
# set(CMAKE_CXX_STANDARD_REQUIRED True)             # 强制使用不低于指定标准版本的编译器编译，与 CMAKE_CXX_STANDARD 配套。true: 不能低于指定版本。false：首选指定版本，没有可以降级。
# set(CMAKE_BUILD_TYPE Release)                     # 设置构建类型，CMake 提供了包括 Debug、Release、RelWithDebInfo 和 MinSizeRel。使用 Debug 模式进行编译可以 set(CMAKE_BUILD_TYPE Debug)
# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2")     # 开启O2级别优化

# * 报错问题解决:

# * 兼容问题解决：
set(COMPAT_SUPPORT_LIBRARY_ARRAY "")
if(WIN32)
    message(STATUS "正在准备 windows 的项目通用设置")
    list(APPEND COMPAT_SUPPORT_LIBRARY_ARRAY ws2_32)
elseif(APPLE)
    message(STATUS "正在准备 Apple 的项目通用设置")
elseif(UNIX)
    message(STATUS "正在准备 Apple 的项目通用设置")
endif()
message(STATUS "兼容依赖库包括：" ${COMPAT_SUPPORT_LIBRARY_ARRAY})
link_libraries(${COMPAT_SUPPORT_LIBRARY_ARRAY})

# * 公共库目录添加：
set(COMMON_SUPPORT_LIBRARY_ARRAY
    # 增加 C 多线程库支持
    pthread
)
message(STATUS "公共依赖库包括：" ${COMMON_SUPPORT_LIBRARY_ARRAY})
link_libraries(${COMMON_SUPPORT_LIBRARY_ARRAY})


# 添加子模块: CommonSupport、LearnAlgorithm、LearnCase、LearnDesignPattern、LearnSerialization、LearnSocket、LearnThread
add_subdirectory(LearnDemoApp)
add_subdirectory(CommonSupport)
add_subdirectory(LearnAlgorithm)
add_subdirectory(LearnCase)
add_subdirectory(LearnDesignPattern)
add_subdirectory(LearnSerialization)
add_subdirectory(LearnSocket)
add_subdirectory(LearnThread)